﻿using AutoMapper;
using Max.PH6_2006A.LowCode.Common;
using Max.PH6_2006A.LowCode.IRespository;
using Max.PH6_2006A.LowCode.IService;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Max.PH6_2006A.LowCode.Service
{
    public class BaseService<TEntity,TInputDto, TOutputDto> : IBaseService<TEntity,TInputDto,TOutputDto> where TEntity : class, new()
    {
        IBaseRespository<TEntity> _respository;
        IMapper _map;

        public BaseService(IBaseRespository<TEntity> respository, IMapper map)
        {
            _respository = respository;
            _map = map;
        }

        public async Task<int> DeleteAsync(List<string> ids,string tableName)
        {
            string sql = $"delete from {tableName} where id =  @ids";
            int result = await _respository.ExecuteAsync(sql, new { ids = ids });
            return result;
        }

        public async Task<int> DeleteAsync(List<TEntity> list)
        {
            string tableName = typeof(TEntity).Name;
            string sql = $"delete from {tableName} where id=@id";
            int result = await _respository.ExecuteAsync(sql, list);
            return result;
        }

        public int Execute(string sql, object? param = null, IDbTransaction? transcation = null, int? commandTimeut = null, CommandType? commandType = null)
        {
            int result = _respository.Execute(sql, param, transcation, commandTimeut, commandType);
            return result;
        }

        public async Task<int> ExecuteAsync(string sql, object? param = null, bool startTran = false, int? commandTimeut = null, CommandType? commandType = null)
        {
            int result = await _respository.ExecuteAsync(sql, param, startTran, commandTimeut, commandType);
            return result;
        }

        public async Task<int> InsertAsync(TInputDto entity,string tableName)
        {
            string sql = Common.ReflectionHelper.EntityToDapperInsertSql(entity,tableName);
            int result =  await _respository.ExecuteAsync(sql, entity);
            return result;
        }

        public async Task<int> InsertAsync(TEntity t)
        {
            string sql = ReflectionHelper.EntityToDapperInsertSql(t);
            int result = await _respository.ExecuteAsync(sql, t);

            return result;
        }

        public IEnumerable<TEntity> Query(string sql, object? param = null, IDbTransaction? transcation = null, bool buffered = true, int? commandTimeut = null, CommandType? commandType = null)
        {
            IEnumerable<TEntity> result = _respository.Query(sql, param, transcation, buffered, commandTimeut, commandType);
            return result;
        }

        //public async Task<IEnumerable<TOutputDto>> QueryAsync(string sql,object? param=null)
        //{
        //    var list = await  _respository.QueryAsync(sql,param);

        //    //将TEntity转换为TOutputDto
        //    IEnumerable<TOutputDto> result = _map.Map<IEnumerable<TEntity>, IEnumerable<TOutputDto>>(list);
        //    return result;

        //}

        public async Task<IEnumerable<TOutputDto>> QueryAsync(string sql, object? param = null, IDbTransaction? transcation = null, int? commandTimeut = null, CommandType? commandType = null)
        {
            IEnumerable<TEntity> list = await _respository.QueryAsync(sql, param, transcation, commandTimeut, commandType);

            //将TEntity转换为TOutputDto
            IEnumerable<TOutputDto> result = _map.Map<IEnumerable<TEntity>, IEnumerable<TOutputDto>>(list);
            return result;
        }

        public async Task<Tuple<IEnumerable<TEntity>, int>> QueryAsync(int pageIndex, int PageSize, string sql, object? param = null, IDbTransaction? transcation = null, int? commandTimeut = null, CommandType? commandType = null)
        {
            IEnumerable<TEntity> result = await _respository.QueryAsync(sql, param, transcation, commandTimeut, commandType);

            int count = result.Count(); //总条数

            var data = result.Skip((pageIndex - 1) * PageSize).Take(PageSize);  //数据分页

            return Tuple.Create(data, count);
        }

        public async Task<Tuple<IEnumerable<dynamic>, int>> QueryDynamicAsync(int pageIndex, int PageSize, string sql, object? param = null)
        {
            IEnumerable<dynamic> result = await _respository.QueryDynamicAsync(sql, param);

            int count = result.Count(); //总条数

            var data = result.Skip((pageIndex - 1) * PageSize).Take(PageSize);  //数据分页

            return Tuple.Create(data, count);
        }


        public TEntity QueryFirst(string sql, object? param = null, IDbTransaction? transcation = null, int? commandTimeut = null, CommandType? commandType = null)
        {
            Console.WriteLine(sql);
            TEntity result = _respository.QueryFirst(sql, param, transcation, commandTimeut, commandType);
            return result;
        }

     
        public async Task<TEntity> QueryFirstAsync(string sql, object? param = null, IDbTransaction? transcation = null, int? commandTimeut = null, CommandType? commandType = null)
        {
            TEntity result = await _respository.QueryFirstAsync(sql, param, transcation, commandTimeut, commandType);
            return result;
        }

        public async Task<int> UpdateAsync(TEntity entity)
        {
            string sql = Common.ReflectionHelper.EntityToDapperUpdateSql<TEntity>(entity);
            int result = await _respository.ExecuteAsync(sql,entity);
            return result;            
        }
    }
}
